# -*- coding: utf-8 -*-
"""
author:lili
date:20190422
produce item sim file
"""

import os
import numpy as np
import operator
import sys
sys.path.append('/home/lili/project/recommend/pyrcd/personal_recommendation')
import Item2Vec.util.reader as reader
import LR.util.test_cvs as tc
import LR.util.lrsort as lrs
import LR.production.check as ck

def load_item_vec(input_file):
    """
    Args:
        input_file: item vec file
    Return:
        dict key:itemid value:np.array([num1, num2....])
    """
    if not os.path.exists(input_file):
        return {}
    linenum = 0
    item_vec = {}
    fp = open(input_file)
    for line in fp:
        if linenum == 0:
            linenum += 1
            continue
        item = line.strip().split()
        if len(item) < 129:
            continue
        itemid = item[0]
        if itemid == "</s>":
            continue
        item_vec[itemid] = np.array([float(ele) for ele in item[1:]])
    fp.close()
    return item_vec


def cal_item_sim(item_vec, itemid, output_file):
    """
    Args
        item_vec:item embedding vector 
        itemid:fixed itemid to clac item sim
        output_file: the file to store result
    """
    if itemid not in item_vec:
        return
    score = {}
    topk = 10
    fix_item_vec = item_vec[itemid]
    for tmp_itemid in item_vec:
        if tmp_itemid == itemid:
            continue
        tmp_itemvec = item_vec[tmp_itemid]
        fenmu = np.linalg.norm(fix_item_vec) * np.linalg.norm(tmp_itemvec)
        if fenmu == 0:
            score[tmp_itemid] = 0
        else:
            score[tmp_itemid] =  round(np.dot(fix_item_vec, tmp_itemvec)/fenmu, 3) #遍历求itemid向量和其他的向量的相似度，找出前几名的item
    fw = open(output_file, "w+")
    out_str = itemid + "\t"
    tmp_list = []
    for zuhe in sorted(score.iteritems(), key = operator.itemgetter(1), reverse = True)[:topk]:
        tmp_list.append(zuhe[0] + "_" + str(zuhe[1]))
    out_str += ";".join(tmp_list)
    fw.write(out_str + "\n")
    fw.close()




def run_main(input_file, output_file):
    item_vec = load_item_vec(input_file)
    cal_item_sim(item_vec, "27", output_file)

def cal_item_sim_dict(item_vec, itemid):
    """
    返回item的相似度高的item
    Args
        item_vec:item embedding vector 
        itemid:fixed itemid to clac item sim
        return :dict key itemid value {'itemid':'score'}
    """
    if itemid not in item_vec:
        return
    score = {}
    topk = 10
    sim_result={}
    fix_item_vec = item_vec[itemid]
    for tmp_itemid in item_vec:
        if tmp_itemid == itemid:
            continue
        tmp_itemvec = item_vec[tmp_itemid]
        fenmu = np.linalg.norm(fix_item_vec) * np.linalg.norm(tmp_itemvec)
        if fenmu == 0:
            score[tmp_itemid] = 0
        else:
            score[tmp_itemid] =  round(np.dot(fix_item_vec, tmp_itemvec)/fenmu, 3) #遍历求itemid向量和其他的向量的相似度，找出前几名的item
    # print score
    sim_result[itemid] = {}
    for zuhe in sorted(score.iteritems(), key = operator.itemgetter(1), reverse = True)[:topk]:
        sim_result[itemid][zuhe[0]] = str(zuhe[1])
    return sim_result

#通过uid获得推荐列表
def get_recom_result_uid(item_vec,uid):
    """
        通过uid获得推荐列表
        Args
            item_vec:item embedding vector 向量矩阵
            uid:fixed uid 我们要求uid的推荐列表
            return :dict key uid value {'itemid':'score'}
        """
    uid = str(uid)
    recent_click_num=20
    user_click, user_click_time = reader.get_user_click("/home/lili/project/recommend/ll_newscms/public/data/rating.txt") #获得点击记录
    recom_info = {}
    recom_info.setdefault(uid, {})
    if not(user_click.has_key(uid)) :
        #不存在返回空字典
        return recom_info
    click_list = user_click[uid] #某个用户的点击列表
    for itemid in click_list[:recent_click_num]:
        # 遍历最近点击过的itemid
        sim_dict = cal_item_sim_dict(item_vec, itemid) #每一个item的相似item
        if sim_dict is None:
            continue #为空，跳过
        for sitem in sim_dict[itemid].items():
            #遍历每一个推荐item
            if recom_info[uid].has_key(sitem[0]):
                #如果有和这个key，叠加，否则，插入
                recom_info[uid][sitem[0]]= float(recom_info[uid][sitem[0]]) + float(sitem[1])
            else:
                recom_info[uid][sitem[0]]= sitem[1]

    return recom_info


#web返回的接口
def web_return(uid):
    input_file='/home/lili/project/recommend/ll_newscms/public/data/Item2Vec/item_vec.txt'
    item_vec = load_item_vec(input_file) #item向量矩阵
    recom_info=get_recom_result_uid(item_vec,uid) #通过uid获得推荐列表 dict key uid value {'itemid':'score'}

    # #lr排序
    # recom_info=lrs.lrsort(recom_info,uid)

    # itemidsstr=tc.recdic_to_str(recom_info[str(uid)]) #字典提取itemid 字符串
    # tc.test_data_cvs(uid,itemidsstr) #把测试集的itemid导出cvs
    # recom_info={}
    # recom_info[str(uid)] = ck.web_return("/home/lili/project/recommend/ll_newscms/public/data/lr/test_file", "/home/lili/project/recommend/ll_newscms/public/data/lr/lr_coef", "/home/lili/project/recommend/ll_newscms/public/data/lr/lr_model", "/home/lili/project/recommend/ll_newscms/public/data/lr/feature_num")
    # print recom_info
    return recom_info


if __name__ == "__main__":
    web_return(20)
    # if len(sys.argv) < 3:
    #     print "usage: python xx.py inputfile outputfile"
    #     sys.exit()
    # else:
    #     inputfile = sys.argv[1]
    #     outputfile = sys.argv[2]
    #     run_main(inputfile, outputfile)
        #run_main("../data/item_vec.txt", "../data/sim_result.txt")